package com.xc.hotelmgr.webapi.modules.ord.service.impl;

import com.xc.hotelmgr.webapi.common.utils.DateUtils;
import com.xc.hotelmgr.webapi.common.utils.R;
import com.xc.hotelmgr.webapi.common.utils.RedisUtils;
import com.xc.hotelmgr.webapi.modules.dt.entity.DtOrderChannelsEntity;
import com.xc.hotelmgr.webapi.modules.dt.service.DtOrderChannelsService;
import com.xc.hotelmgr.webapi.modules.ht.dao.HtLogicRoomDao;
import com.xc.hotelmgr.webapi.modules.ht.entity.HtDailyroomEntity;
import com.xc.hotelmgr.webapi.modules.ht.entity.HtLogicRoomEntity;
import com.xc.hotelmgr.webapi.modules.ord.dao.OrdDailyInfoDao;
import com.xc.hotelmgr.webapi.modules.ord.dao.OrdGuestDao;
import com.xc.hotelmgr.webapi.modules.ord.entity.DeliGood;
import com.xc.hotelmgr.webapi.modules.ord.entity.OrdDailyInfoEntity;
import com.xc.hotelmgr.webapi.modules.ord.entity.OrdGuestEntity;
import com.xc.hotelmgr.webapi.modules.ord.entity.OrdOrderEntity;
import com.xc.hotelmgr.webapi.modules.ord.service.OrdOrderService;
import com.xc.hotelmgr.webapi.modules.ord.service.OrderDealService;
import com.xc.hotelmgr.webapi.modules.ord.service.OrderFeignService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@RequiredArgsConstructor
public class OrderDealServiceImpl implements OrderDealService {

    private final OrdOrderService ordOrderService;

    private final OrdGuestDao ordGuestDao;

    private final OrderFeignService orderFeignService;

    private final RedisUtils redisUtils;

    private final HtLogicRoomDao htLogicRoomDao;

    private final OrdDailyInfoDao ordDailyInfoDao;

    private final DtOrderChannelsService dtOrderChannelsService;

    private static final String RATES_HASH_H_PREFIX = "r"; // rates hash h前缀

    private static final String RATES_HASH_HK_PRICE = "p"; //rates hash 价格 hk

    private static final String RATES_HASH_HK_NUM = "n"; //rates hash 价格 hk



    @Override
    @Transactional
    public List<Map<String, Object>> getRatesList(Integer id) {
        OrdOrderEntity ordOrderEntity = ordOrderService.getById(id);

        List<Map<String, Object>> list = new ArrayList<>();
        Integer channel = ordOrderEntity.getBuySource();
        Integer storeId = ordOrderEntity.getDtStoreId();
        Long rpCode = ordOrderEntity.getRateplanCode();
        Date startDate = ordOrderEntity.getCheckInDate();
        Date endDate = ordOrderEntity.getCheckOutDate();
        DtOrderChannelsEntity dtOrderChannelsEntity = dtOrderChannelsService.getByStoreIdAndChanel(storeId, channel);

        Integer commRateMt = dtOrderChannelsEntity.getCommRate();                  // 美团佣金
        Integer commRateFz = dtOrderChannelsEntity.getCommRateFz();                // 飞猪佣金
        Integer totalPrice = ordOrderEntity.getTotalPrice();                       // 售卖价格
        Integer payPrice = ordOrderEntity.getPayPrice();                           // 客人实际支付价格
        Integer reducedPrice = ordOrderEntity.getReducedPrice();                   // 优惠价格

        Integer dateNum = Integer.valueOf(DateUtils.suDates(endDate, startDate).toString()); // 预定日期跨度
        Integer buyPrice = 0;                                                      // 数据库价格
        for (int i = 0; i < dateNum; i++) {
            String buyDate = DateUtils.format(DateUtils.addDateDays(startDate, i));
            String result = buyDate.substring(buyDate.length()-5).replace("-","");
            buyPrice += (Integer) redisUtils.hashGet(RATES_HASH_H_PREFIX + rpCode + result, RATES_HASH_HK_PRICE);
//            buyPrice = 50000;
        }

        Integer buyFxMt = buyPrice*(1000-commRateMt)/1000;   // 分销支付价格
        Integer buyFxFz = payPrice*(1000-commRateFz)/1000;
        Integer profit = buyFxFz - buyFxMt; // 利润

        HtLogicRoomEntity htLogicRoomEntity = htLogicRoomDao.getRpByRpCode(rpCode);
        String name = htLogicRoomEntity.getRpName();     // rp名字
        Map<String, Object> map = new HashMap<>();
        map.put("rpCode", rpCode);
        map.put("name", name);
        String pf = "美团";
        if(rpCode<0) {
            pf="携程";
        }
        map.put("pf", pf);
        map.put("totalPrice", totalPrice);
        map.put("reducedPrice", reducedPrice);
        map.put("payPrice", payPrice);
        map.put("buyPrice", buyPrice);
        map.put("profit", profit);
        map.put("buyFxMt", buyFxMt);
        map.put("buyFxFz", buyFxFz);
        list.add(map);
        return list;
    }

    @Override
    @Transactional
    public R buy(Long id, Long rpCode, Long userId) {
        OrdOrderEntity orderEntity = ordOrderService.getById(id);
        Long orderCode = orderEntity.getOrderCode();
        Long ordDealPeo = Long.valueOf(orderEntity.getDealOrderPeo().toString());
        if (!ordDealPeo.equals(userId)) {
            return R.error(-1,"跟单人不符");
        }
        List<OrdGuestEntity> ordGuestEntities = ordGuestDao.getByOrderCode(orderCode);
        orderEntity.setOrderGuests(ordGuestEntities);

        Date startDate = orderEntity.getCheckInDate();
        Date endDate = orderEntity.getCheckOutDate();
        List<HtDailyroomEntity> htDailyroomEntities = new ArrayList<>();
        Integer dateNum = Integer.valueOf(DateUtils.suDates(endDate, startDate).toString());
        for (int i = 0; i < dateNum; i++) {
            HtDailyroomEntity htDailyroomEntity = new HtDailyroomEntity();
            Date date = DateUtils.addDateDays(startDate, i);
            String buyDate = DateUtils.format(date);
            String result = buyDate.substring(buyDate.length() - 5).replace("-", "");
            Integer sellPrice = null;
            Integer sellNum = null;
            sellPrice = (Integer) redisUtils.hashGet(RATES_HASH_H_PREFIX + rpCode + result, RATES_HASH_HK_PRICE);
            sellNum = (Integer) redisUtils.hashGet(RATES_HASH_H_PREFIX + rpCode + result, RATES_HASH_HK_NUM);
            Long ratesId = Long.valueOf(rpCode + result);
            htDailyroomEntity.setId(ratesId);
            htDailyroomEntity.setPrice(sellPrice);
            htDailyroomEntity.setSaleNum(sellNum);
            htDailyroomEntity.setRpCode(rpCode);
            htDailyroomEntity.setPriceDate(date);
            htDailyroomEntities.add(htDailyroomEntity);
        }
        orderEntity.setDailyRooms(htDailyroomEntities);
        R r = orderFeignService.manuOrder(orderEntity);
        int code = (int) r.get("code");
        if(code!=0) {
            String message = (String)r.get("msg");
            return R.error(message);
        }
        return R.ok();
    }

    @Override
    @Transactional
    public R getLock(Integer userId, Long id, String username) {
        // 人工订单跟单条件   跟单人为null
        // 直连订单跟单条件   跟单人为null 采购状态失败
        OrdOrderEntity ordOrderEntity = ordOrderService.getById(id);
        Integer dealOrderPeo = ordOrderEntity.getDealOrderPeo();
        Integer buyStatus = ordOrderEntity.getBuyStatus();
        Integer orderType = ordOrderEntity.getOrderType();

        if(orderType == 0) {   // 人工订单
            if(dealOrderPeo != null) { // 已跟单
                return R.error(-1,"订单已受理");
            }else {
                ordOrderEntity.setUsername(username);
                ordOrderEntity.setBuyStatus(1); // 设置采购状态为已受理
            }
        }else {  // 直连订单
            if (dealOrderPeo == null || buyStatus == -1) { // 直连订单当没有跟单人和采购失败时候才能跟单处理
                ordOrderEntity.setBuyStatus(1); // 设置采购状态为已受理
            } else {
                ordOrderEntity.setUsername(username);
                return R.error(-1, "订单已受理");
            }
        }
        ordOrderEntity.setDealOrderPeo(userId);
        ordOrderService.updateById(ordOrderEntity);
        return R.ok();
    }

    @Override
    @Transactional
    public R buyOther(Long id, Long userId, Integer optType, Integer status, Integer price, String orderCodeOther) {
        OrdOrderEntity orderEntity = ordOrderService.getById(id);
        Long orderCode = orderEntity.getOrderCode();
        Long ordDealPeo = Long.valueOf(orderEntity.getDealOrderPeo().toString());
        if (!ordDealPeo.equals(userId)) {
            return R.error(-1,"跟单人不符");
        }

        // 下单
        DeliGood deliGood = new DeliGood();
        deliGood.setOptType(optType);
        deliGood.setOrderCode(orderCode);
        R r = orderFeignService.manudeligood(deliGood);
        int code = (int) r.get("code");
        if(code!=0) {
            String message = (String)r.get("msg");
            return R.error(message);
        }

        // 更改数据库价格，添加渠道订单号
        OrdOrderEntity ordOrderEntity = new OrdOrderEntity();

        ordOrderEntity.setId(id);
        ordOrderEntity.setBuyStatus(3);
        ordOrderEntity.setBuyOrderPrice(price);
        ordOrderEntity.setBuyOrderId(orderCodeOther);
        ordOrderEntity.setBuySource(status); // 自采订单
        ordOrderService.updateById(ordOrderEntity);
        return R.ok();
    }

    @Override
    @Transactional
    public R refuse(Long id, Integer optType, Long userId) {
        OrdOrderEntity orderEntity = ordOrderService.getById(id);
        Long ordDealPeo = Long.valueOf(orderEntity.getDealOrderPeo().toString());
        Long orderCode = orderEntity.getOrderCode();

        if (!ordDealPeo.equals(userId)) {
            return R.error(-1,"跟单人不符");
        }
        DeliGood deliGood = new DeliGood();
        deliGood.setOptType(optType);
        deliGood.setOrderCode(orderCode);
        R r = orderFeignService.manudeligood(deliGood);
        int code = (int) r.get("code");
        if(code!=0) {
            String message = (String)r.get("msg");
            return R.error(message);
        }
        return R.ok();
    }
}
